package com.example.tests;

import java.util.ArrayList;

import org.junit.BeforeClass;
import org.junit.Test;

import com.example.model.Item;
import com.example.model.ItemList;

import junit.framework.TestCase;

public class ItemFiltertingTest extends TestCase {
	// A series of items to use for testing.
	private static Item couch;
	private static Item tv;
	private static Item donated_soap;
	private static Item photo_album;
	private static Item kitchen_supplies;

	// Two lists for testing. One with the above items for testing. The other
	// for testing when item list object is null.
	private static ItemList list = ItemList.getEmptyList();

	// List of tags to use for testing.
	private static String furniture = "Furniture";
	private static String electronics = "Electronics";
	private static String other = "Other";
	private static String pet = "Pets";
	private static String clothes = "Clothes";
	private static String housewares = "Housewares";

	// ArrayLists of tags for testing purposes
	private static ArrayList<String> furniture_tags = new ArrayList<String>();
	private static ArrayList<String> electronic_tags = new ArrayList<String>();
	private static ArrayList<String> empty_tags = new ArrayList<String>();
	private static ArrayList<String> multiple_tags = new ArrayList<String>();
	private static ArrayList<String> not_included_tags = new ArrayList<String>();

	/**
	 * Sets up the information and files required to run this test. It will
	 * create a list of items with different information and tags, a couple of
	 * users these items belong to, a set of tags to search for, and other
	 * pertinent information that becomes necessary for testing.
	 */
	@BeforeClass
	public void setUp() {

		furniture_tags.add(furniture);
		electronic_tags.add(electronics);
		multiple_tags.add(other);
		multiple_tags.add(pet);
		not_included_tags.add(clothes);

		// Sets up the necessary Items for testing.
		couch = new Item("Couch");
		couch.addTag(furniture);

		tv = new Item("TV");
		tv.addTag(electronics);

		donated_soap = new Item("Soap");
		donated_soap.addTag(other);
		donated_soap.setStatus(2);

		photo_album = new Item("Pet Photo Album");
		photo_album.addTag(other);
		photo_album.addTag(pet);

		kitchen_supplies = new Item("Knives and Utensils");
		kitchen_supplies.addTag(housewares);

		// Creates the list and adds all revelant items to the list
		list.add(couch);
		list.add(tv);
		list.add(donated_soap);
		list.add(photo_album);
		list.add(kitchen_supplies);

	} // End of setUp method

	@Test
	public void testListIsNotNull() {
		assertTrue(list != null);
	}

	@Test
	public void testListContainsAllItems() {
		assertTrue(list.contains(couch));
		assertTrue(list.contains(tv));
		assertTrue(list.contains(donated_soap));
		assertTrue(list.contains(photo_album));
		assertTrue(list.contains(kitchen_supplies));
	}

	@Test
	public void testFurnitureFound() {
		ArrayList<Item> results = list.getMatchItems(furniture_tags);
		assertTrue(results.contains(couch));
	}

	@Test
	public void testEletronicsFound() {
		ArrayList<Item> results = list.getMatchItems(electronic_tags);
		assertTrue(results.contains(tv));
	}

	@Test
	public void testNothingFound() {
		ArrayList<Item> results = list.getMatchItems(not_included_tags);
		assertTrue(results.isEmpty());
	}

	@Test
	public void testEmptyTagListReturnsAllItems() {
		ArrayList<Item> results = list.getMatchItems(empty_tags);
		assertTrue(results.contains(couch));
		assertTrue(results.contains(tv));
		assertTrue(results.contains(donated_soap));
		assertTrue(results.contains(photo_album));
		assertTrue(results.contains(kitchen_supplies));
	}

	@Test
	public void testMultipleTagsMatchItem() {
		ArrayList<Item> results = list.getMatchItems(multiple_tags);
		assertTrue(results.contains(photo_album));
	}

	@Test
	public void testForNullTagList() {
		try {
			ArrayList<Item> results = list.getMatchItems(null);
			fail("There should've been an exception here");
		} catch (NullPointerException e) {
			// Test passes. Success!
		}
	}
} // End of test method.
